home *** CD-ROM | disk | FTP | other *** search
/ PC World Interactive 11 / PC World Interactive 11.iso / share / convert / cel2pcx.lzh / CEL2PCX.CPP next >
C/C++ Source or Header  |  1994-03-13  |  5KB  |  190 lines

  1. #include <fstream.h>
  2. #include <malloc.h>
  3. #include <string.h>
  4. #include "pcx2cel.h"
  5.  
  6. #define BSIZE 16384
  7. #define HIMASK 0xF0
  8. #define LOMASK 0xF
  9.  
  10. byte Palblock[768];
  11. pcxHeader PcxH;
  12.  
  13.  
  14. void headerInit() {
  15.    PcxH.maker=0xA;
  16.    PcxH.version=5;
  17.    PcxH.code=1;
  18.    PcxH.bpp=8;
  19.    PcxH.x1=0; PcxH.y1=0;
  20.    PcxH.hres=0x96;
  21.    PcxH.vres=0x96;
  22.    for (int i=0; i<48; i++)
  23.       PcxH.tripletData[i]=Palblock[i+1]; //16 col palette area.
  24.    PcxH.vmode=0;
  25.    PcxH.numPlanes=1;
  26.    PcxH.paletteFlag=1;
  27.    for (i=0; i<58; i++)
  28.       PcxH.unusedData[i]=0;
  29. }
  30.  
  31.  
  32. int readKCF(char *in) {
  33.  
  34. byte *paltemp=new byte[320];
  35. byte *poshold=paltemp;
  36. byte *Pblockpos=Palblock;
  37.  
  38. ifstream myInStream(in, ios::binary);
  39.   if (!myInStream) {
  40.     cerr << in << ": Cannot open input file\n";
  41.     delete paltemp;
  42.     return 1;
  43.   }
  44. *Pblockpos++=12; //Initial 12 value sep pic from palette.
  45. myInStream.read(paltemp, 320);
  46. for (int i=0; i<160; i++) {
  47.   *Pblockpos++=(HIMASK & *poshold); //mult by 16 upper nibble; R
  48.   *Pblockpos++=(LOMASK & *(poshold+1)) <<4; //mult by 16 lower nibble; G
  49.   *Pblockpos++=(LOMASK & *poshold) <<4; // B value
  50.   poshold+=2; }
  51.  
  52. for (i=0; i<288; i++)
  53.   *Pblockpos++=0;  //zero out remaining entries
  54. myInStream.close();
  55. //At this point, block filled with palvals.  Others written will be 0.
  56.  
  57. return 0;
  58. }
  59.  
  60. void RLEblock(int &val, int &lastval, long &writecount, int &count, byte *&outpos) {
  61.  if (val==lastval) {
  62.      count++;
  63.      if (count==63){
  64.        *outpos++=0xC0 | count; *outpos++=lastval; writecount+=2; count=0;}
  65.   } else { //this case, new val trigger.
  66.   if (count) {
  67.     if (count >1) {
  68.       *outpos++=0xC0 | count; *outpos++=lastval; writecount+=2;
  69.    } else {
  70.       *outpos++=lastval; writecount++; }
  71.    lastval=val;
  72.    count=1;
  73.   }//if (count)
  74.   } //else
  75. }
  76.  
  77. int convertCELPic(char *in, char *out) {
  78. byte *inbuffer=new byte[BSIZE];
  79. byte *outbuffer=new byte[BSIZE*2];
  80. byte buf[128];
  81. byte *inbuf=buf;
  82. struct sizedat{
  83.    int width, height;
  84. } sizedata;
  85. sizedat *sizeptr=&sizedata;
  86.  
  87. ifstream myInStream(in, ios::binary);
  88.   if (!myInStream) {
  89.     cerr << in << ": Cannot open input file\n";
  90.     delete inbuffer;
  91.     delete outbuffer;
  92.     return 1;}
  93. ofstream myOutStream(out, ios::binary);
  94.   if (!myOutStream) {
  95.     cerr << out << ": not able to write file.\n";
  96.     delete inbuffer;
  97.     delete outbuffer;
  98.     return 1;}
  99. myInStream.read(inbuf, 4);
  100. memcpy(sizeptr, inbuf, 4);
  101. PcxH.x2=sizeptr->width-1;
  102. PcxH.y2=sizeptr->height-1;
  103. PcxH.bpl=sizeptr->width + sizeptr->width % 2;
  104.  
  105. //write header block; the breakdown from weirdness.
  106. myOutStream.write((byte *)&PcxH, 128);
  107.  
  108. //write always <=input block.  Keep track of all to write, as well as counter.
  109. //remember that double size of write block due to decompression from nibble
  110.  
  111. int count=0, val;
  112. long writecount=0, totalread=0;
  113. int linesize=PcxH.bpl>>1;
  114. long readmax;
  115. long readlimit=(BSIZE/linesize)*linesize; //round # of lines.
  116. byte *inpos=inbuffer;
  117. byte *outpos=outbuffer;
  118. int lastval=0;
  119. myInStream.seekg(0, ios::end);
  120. long size = myInStream.tellg();
  121. myInStream.seekg(4, ios::beg);
  122.  
  123.  
  124. while (totalread < size) {
  125.   if (size-totalread>BSIZE) readmax=readlimit; else readmax=size-totalread;
  126.   myInStream.read(inbuffer, readmax);
  127.   totalread+=readmax;
  128. for (int i=0; i<readmax; i+=linesize) {
  129.   lastval=(HIMASK & *inpos) >>4; //new line, fresh start
  130.   for (int j=1; j<=linesize; j++) {
  131.     val=(HIMASK & *inpos) >>4;
  132.     RLEblock(val, lastval, writecount, count, outpos);
  133.     if (count==0) lastval=(LOMASK & *inpos); //last=next.
  134.     val=(LOMASK & *inpos);
  135.     RLEblock(val, lastval, writecount, count, outpos);
  136.     if (count==0) lastval=(HIMASK & *(++inpos)) >>4; else *inpos++;
  137.  } //line decode loop
  138.  
  139. //if remaining vals unwritten, write here. finish off.
  140.  if (count) {
  141.    if (count >1) {
  142.      *outpos++=0xC0 | count; *outpos++=lastval; writecount+=2;
  143.   } else {
  144.      *outpos++=lastval; writecount++; }
  145.   count=0;
  146.  }//if (count)
  147.  
  148. } //buffer decode loop
  149.  
  150.  
  151. myOutStream.write(outbuffer, writecount);
  152. writecount=0;
  153. inpos=inbuffer; outpos=outbuffer;
  154. } //while loop
  155.  
  156. myOutStream.write(Palblock, 769);
  157. delete inbuffer; delete outbuffer;
  158. myInStream.close();
  159. myOutStream.close();
  160. return 0;
  161. }
  162.  
  163. int main(int argc, char *argv[]) {
  164.   char *KCFFile;
  165.   char *filein;
  166.   char fileout[15];
  167.   char *temp;
  168.  
  169.   if (argc<3) {
  170.     cerr << "Must be in format: cel2pcx <.kcf file> <.cel to convert> ...\n";
  171.     cerr << "The .kcf and .cel suffixes must be included.\n";
  172.     return 0; }
  173.   KCFFile=argv[1];
  174.   if (readKCF(KCFFile)) return 0;
  175.   headerInit(); //inits headerblock;
  176.   for (int i=2; i<argc; i++) { //remaining args for file names
  177.     filein=argv[i];
  178.     temp=filein;
  179.     for (int j=0; *temp!='.'; j++, temp++)
  180.       fileout[j]=*temp;
  181.     fileout[j]='\0';
  182.     strcat(fileout, ".pcx\0");
  183.   if (!convertCELPic(filein, fileout))
  184.       cerr << filein << " converted \n";
  185.   else
  186.       cerr << filein << " not converted.\n";
  187.   }
  188.   cerr << "Done.\n";
  189. return 0;
  190. }